package com.gemantic.config;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.HttpMessageConverterExtractor;
import org.springframework.web.client.RequestCallback;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;

public class DIYRestTemplate extends RestTemplate {
    public DIYRestTemplate(SimpleClientHttpRequestFactory requestFactory) {
        super(requestFactory);
    }

    public <T> T sendForObject(String url, HttpMethod method, Object request, Class<T> responseType, Object... uriVariables)
            throws RestClientException {

        RequestCallback requestCallback = httpEntityCallback(request, responseType);
        HttpMessageConverterExtractor<T> responseExtractor =
                new HttpMessageConverterExtractor<T>(responseType, getMessageConverters());
        return execute(url, method, requestCallback, responseExtractor, uriVariables);
    }

    private <T> T sendJson(String url, HttpMethod method, Object jsonable, Class<T> clazz, Object... uriVariables) {
        String json = JSON.toJSONString(jsonable);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<String> entity = new HttpEntity<String>(json, headers);
        try {
            String resBody = sendForObject(url, method, entity, String.class, uriVariables);
            return JSON.parseObject(resBody, clazz);
        } catch (Exception e) {
            logger.error("postJson " + jsonable.toString() + "\nerror: " + e.toString());
            e.printStackTrace();
            return null;
        }
    }

    public  <T> T postJson(String url, Object jsonable, Class<T> clazz, Object... uriVariables) {
        return sendJson(url, HttpMethod.POST, jsonable, clazz, uriVariables);
    }

    public  <T> T deleteJson(String url, Object jsonable, Class<T> clazz, Object... uriVariables) {
        return sendJson(url, HttpMethod.DELETE, jsonable, clazz, uriVariables);
    }

    public HashMap<String, Object> getResponse(String url, Object... uriVariables) {
        HashMap<String,Object> result = new HashMap<String, Object>();
        try {
            String resBody = getForObject(url, String.class, uriVariables);
            result = new ObjectMapper().readValue(resBody, HashMap.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
}
